home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-19
/
surfsrc3.zip
/
PALETTE.INC
< prev
next >
Wrap
Text File
|
1991-09-30
|
11KB
|
359 lines
{ PALETTE.INC: Support for large-palette multicolor graphics in SURFMODL. }
{ RGB2pal: Convert RGB triplet into a Palettetype record }
procedure RGB2pal (r, g, b: integer; var col: ColorValue);
begin
with col do begin
{ Make sure values are valid }
if r < 0 then
Rvalue := 0
else if r > RGB_levels then
Rvalue := RGB_levels
else
Rvalue := r;
if g < 0 then
Gvalue := 0
else if g > RGB_levels then
Gvalue := RGB_levels
else
Gvalue := g;
if b < 0 then
Bvalue := 0
else if b > RGB_levels then
Bvalue := RGB_levels
else
Bvalue := b;
end;
end; { procedure RGB2pal }
{ def_palette: Define the graphics palette for all materials. }
procedure def_palette (Nmatl: integer);
var Mat: integer; { material # }
Done: boolean; { are we done searching for correct # steps? }
Del: array[1..3] of integer; { deltas for R, G and B }
Nsteps: integer; { # color steps from 0 to full intensity }
i: integer;
j: integer;
Shade: real;
curr: integer; { current color # being printed }
r, g, b: integer;
begin
if RGB_levels > 1 then begin
{ Set the maximum number of colors used per material }
Maxcol_mat := (Ncolors-RESERVED_COLORS) div Nmatl;
if MAXSHADES < Maxcol_mat then
Maxcol_mat := MAXSHADES;
if RGB_levels < Maxcol_mat then
Maxcol_mat := RGB_levels;
if Maxcol_mat < 2 then begin
restorecrtmode;
writeln;
writeln ('ERROR: Not enough colors to define a palette!');
writeln ('You have ', Nmatl, ' materials and only ',
Ncolors-RESERVED_COLORS, ' colors available.');
writeln (' (need at least 2 colors per material).');
{$ifdef USE_IFF}
writeln ('This file can not be displayed with SURFIFF.');
{$else}
writeln ('Suggest you set your GRSYS to VGA without 256-color');
writeln (' capability, or use EGA instead.');
{$endif}
halt(1);
end;
{$ifdef DEBUG}
writeln(Dbgfile, 'Ncolors=', Ncolors, ' Maxcol_mat=', Maxcol_mat);
{$endif}
{ if grsys = VGA256 then begin }
{ Reserve some colors for their standard EGA values: }
for curr := 0 to RESERVED_COLORS-1 do begin
color_to_rgb (curr, r, g, b);
if grsys = VGA256 then begin
{ These came back in 1..256 range, so scale to 0..RGB_levels }
r := r * (RGB_levels + 1) div 256 - 1;
g := g * (RGB_levels + 1) div 256 - 1;
b := b * (RGB_levels + 1) div 256 - 1;
{$IFDEF USE_IFF}
end else if grsys = IFF then begin
{ These came back in 1..256 range, so make them 0..255 }
r := r - 1;
g := g - 1;
b := b - 1;
{$ENDIF}
end;
RGB2pal (r, g, b, VGApal[curr]);
{$ifdef DEBUG}
writeln(Dbgfile, 'RESPAL ', curr, ': ',
VGApal[curr].Rvalue, ', ', VGApal[curr].Gvalue, ', ',
VGApal[curr].Bvalue);
{$endif}
end;
{ end; { if grsys = VGA256 }
{ Do for each material }
for Mat := 1 to Nmatl do begin
{ Redmax, etc. are in the range 1..256 so we scale them to the proper
range for the device (0..RGB_levels) }
Del[1] := round ((1.0 + RGB_levels) * Redmax[Mat] / 256.0) - 1;
Del[2] := round ((1.0 + RGB_levels) * Grnmax[Mat] / 256.0) - 1;
Del[3] := round ((1.0 + RGB_levels) * Blumax[Mat] / 256.0) - 1;
for i := 1 to 3 do
if Del[i] < 0 then
Del[i] := 0;
{$ifdef DEBUG}
writeln(Dbgfile, 'MAT ', Mat, ' RGB max=', Redmax[Mat], ', ',
Grnmax[Mat], ', ', Blumax[Mat]);
writeln(Dbgfile, ' Dels=', Del[1], ', ', Del[2], ', ', Del[3]);
{$endif}
{$IFDEF PURE_RGB}
{ Calculate the number of color steps for this matl. Note that we only
choose "pure" colors, that is, colors with RGB components that are
exactly proportional to the maximum RGB components. Therefore you
will use more colors if you choose maximum values that are evenly
divisible.
}
{ The largest possible # color steps is the smallest of: (1) the number
of RGB levels on the device; (2) the max # colors allowed per
material; and (3) the smallest of the RGB components that is > 0.
}
if RGB_levels < Maxcol_mat then
Nsteps := RGB_levels
else
Nsteps := Maxcol_mat;
for i := 1 to 3 do
if (Del[i] > 0) and (Del[i] < Nsteps) then
Nsteps := Del[i];
{ Find a # color steps that evenly divides into each of the RGB levels }
repeat
Done := TRUE;
for i := 1 to 3 do
if (Del[i] div Nsteps) * Nsteps <> Del[i] then
Done := FALSE;
if not Done then begin
Nsteps := Nsteps - 1;
if Nsteps = 1 then
Done := TRUE;
end;
until Done;
{$ELSE} {PURE_RGB}
{ In this version we do not restrict ourselves to "pure" RGB colors.
Instead we just use the maximum number of colors available that
will provide unique values.
}
{ Start with the largest of the 3 color components }
Nsteps := 1;
for i := 1 to 3 do
if Del[i] > Nsteps then
Nsteps := Del[i];
{ Then reduce according to the maximum number of colors allowed }
if Maxcol_mat < Nsteps then
Nsteps := Maxcol_mat;
{$ENDIF} {PURE_RGB}
Ncol_mat[Mat] := Nsteps;
{$ifdef DEBUG}
writeln(Dbgfile, 'MAT ', Mat, ' Ncol_mat=', Nsteps);
{$endif}
if Nsteps = 0 then begin
restorecrtmode;
writeln ('ERROR Nsteps=0 Maxcol_mat=', Maxcol_mat);
halt(1);
end;
Shade := 1.0 / Nsteps;
curr := (Mat-1) * Maxcol_mat + RESERVED_COLORS;
for i := 1 to Nsteps do begin
RGB2pal (round (Shade * Del[1]),
round (Shade * Del[2]), round (Shade * Del[3]), VGApal[curr]);
{$ifdef DEBUG}
writeln(Dbgfile, ' Step ', i, ' Shade=', Shade:6:3, ' curr=', curr,
': ',
VGApal[curr].Rvalue, ', ', VGApal[curr].Gvalue, ', ',
VGApal[curr].Bvalue);
{$endif}
Shade := Shade + 1.0 / Nsteps;
curr := curr + 1;
end;
{ Set unused colors to black }
for i := Nsteps+1 to Maxcol_mat do begin
RGB2pal (0, 0, 0, VGApal[curr]);
{$ifdef DEBUG}
writeln(Dbgfile, ' BLACK Step ', i, ' curr=', curr, ': ',
VGApal[curr].Rvalue, ', ', VGApal[curr].Gvalue, ', ',
VGApal[curr].Bvalue);
{$endif}
curr := curr + 1;
end;
end; { for Mat }
{ Inform the device of the new palette changes }
if grsys = VGA256 then
VGASetAllPalette (VGApal);
end else begin { if RGB_levels }
for Mat := 1 to Nmatl do
Ncol_mat[Mat] := 1;
end;
end; { procedure def_palette }
{ FINDCOLORS: Find the appropriate color numbers to use that bracket
the desired shade, for large-palette devices
}
procedure findcolors (Mat, Matcolor: integer; var Shade: real; var Color1, Color2:
integer);
var col: integer;
i: integer;
Tshade: real;
Dshade: real;
Lshade: real;
label FOUNDSHADE;
begin
if (RGB_levels < 2) or (Mat = 0) then begin
{$ifdef NEVER}
if RevVideo then begin
{$endif}
{ KVC 09/27/91 - Not sure why these colors need to be reversed, but
it works this way on my Hercules:
}
Color2 := 0;
{ Make sure the color is legitimate }
if (Matcolor > Ncolors) then
Color1 := Ncolors
else
Color1 := Matcolor;
{$ifdef NEVER}
end else begin
Color1 := 0;
{ Make sure the color is legitimate }
if (Matcolor > Ncolors) then
Color2 := Ncolors
else
Color2 := Matcolor;
end;
{$endif}
end else begin
if Shade < 0.0 then
Shade := 0.0
else if Shade > 1.0 then
Shade := 1.0;
{ Find 2 colors with intensities that bracket the one we want }
{ First find start of colors for this matl }
Col := (Mat-1) * Maxcol_mat + RESERVED_COLORS;
Dshade := 1.0 / Ncol_mat[Mat];
Tshade := Dshade;
for i := 1 to Ncol_mat[Mat] do begin
if Shade <= Tshade then begin
{ Found the right shades to bracket }
if i = 1 then begin
Color1 := 0; { black }
Lshade := 0.0;
end else begin
Color1 := Col + i - 2;
Lshade := Tshade - Dshade;
end;
Color2 := Col + i - 1;
{ The new shade is relative to the 2 shades that bracket it }
Shade := (Shade - Lshade) / Dshade;
{ Done searching }
goto FOUNDSHADE;
end;
Tshade := Tshade + Dshade;
end;
{ Did not find shade - use highest }
if Ncol_mat[Mat] = 1 then begin
Color1 := 0; { black }
Lshade := 0.0;
end else begin
Color1 := Col + Ncol_mat[Mat] - 2;
Lshade := 1.0 - Dshade;
end;
Color2 := Col + Ncol_mat[Mat] - 1;
{ The new shade is relative to the 2 shades that bracket it }
Shade := (Shade - Lshade) / (1.0 - Lshade);
FOUNDSHADE:
end; { if RGB_levels }
end; { procedure findcolors }
{ COLOR_TO_RGB: Convert an old PC-style color number to its RGB components.
This routine should be fixed up, as these RGB levels are not quite right.
}
procedure color_to_rgb (Color: integer; var Red, Grn, Blu: integer);
begin
case Color of
0: begin { black }
Red := 1; Grn := 1; Blu := 1;
end;
1: begin { blue (dark) }
Red := 1; Grn := 1; Blu := 176; { ??? }
end;
2: begin { green }
Red := 1; Grn := 176; Blu := 1;
end;
3: begin { cyan }
Red := 1; Grn := 176; Blu := 176;
end;
4: begin { red}
Red := 256; Grn := 1; Blu := 80; { ??? }
end;
5: begin { magenta }
Red := 176; Grn := 1; Blu := 176;
end;
6: begin { brown }
Red := 256; Grn := 128; Blu := 256; { ??? }
end;
7: begin { lightgray }
Red := 80; Grn := 80; Blu := 80;
end;
8: begin { darkgray }
Red := 176; Grn := 176; Blu := 176;
end;
9: begin { lightblue }
Red := 1; Grn := 1; Blu := 256;
end;
10: begin { lightgreen }
Red := 1; Grn := 256; Blu := 1;
end;
11: begin { lightcyan }
Red := 1; Grn := 256; Blu := 256;
end;
12: begin { lightred }
Red := 256; Grn := 1; Blu := 176;
end;
13: begin { lightmagenta }
Red := 256; Grn := 1; Blu := 256;
end;
14: begin { yellow }
Red := 256; Grn := 256; Blu := 80;
end;
15: begin { white }
Red := 256; Grn := 256; Blu := 256;
end;
else begin { undefined color = white }
Red := 256; Grn := 256; Blu := 256;
end;
end; { case }
end; { procedure color_to_rgb }